package com.yifei.service.system.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifei.constants.RedisKeyConstants;
import com.yifei.converter.system.UserConverter;
import com.yifei.mapper.SysUserMapper;
import com.yifei.model.bo.system.UserBO;
import com.yifei.model.bo.system.UserFromBO;
import com.yifei.model.dto.auth.UserAuthInfo;
import com.yifei.model.entity.system.SysUser;
import com.yifei.model.form.system.UserForm;
import com.yifei.model.query.system.UserPageQuery;
import com.yifei.model.vo.system.UserInfoVO;
import com.yifei.model.vo.system.UserPageVO;
import com.yifei.service.system.SysMenuService;
import com.yifei.service.system.SysUserService;
import com.yifei.utils.RedisUtil;
import com.yifei.utils.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Set;


/**
 * 用户信息表(SysUser)表服务实现类
 *
 * @author yiFei
 * @since 2023-09-23 20:56:10
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    private SysMenuService menuService;

    @Autowired
    private UserConverter userConverter;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 根据用户名获取认证信息
     *
     * @param username 用户名
     * @return {@link UserAuthInfo}
     */
    @Override
    public UserAuthInfo getUserAuthInfo(String username) {
        // 根据用户名获取一个未被删除的用户
        UserAuthInfo userAuthInfo = this.baseMapper.getUserAuthInfo(username);
        // 如果查询到对象，获取它对应的角色
        if (!ObjectUtils.isEmpty(userAuthInfo)) {
            Set<String> roles = userAuthInfo.getRoles();
            // 如果查询到角色，获取它对应的权限
            if (CollectionUtil.isNotEmpty(roles)) {
                Set<String> perms = menuService.listRolePerms(roles);
                userAuthInfo.setPerms(perms);
            }
        }
        return userAuthInfo;
    }

    /**
     * 用户分页列表
     *
     * @param queryParams 查询参数
     * @return 用户分页列表
     */
    @Override
    public IPage<UserPageVO> getUserPage(UserPageQuery queryParams) {
        // 参数构建
        IPage<UserBO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());

        // 查询数据
        Page<UserBO> userBoPage = this.baseMapper.getUserPage(page, queryParams);

        // 实体转换返回
        return userConverter.bo2Vo(userBoPage);
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 当前用户信息
     */
    @Override
    public UserInfoVO getCurrentUserInfo() {
        // 获取当前登录用户
        Long userId = SecurityUtil.getUserId();

        // 获取登录用户基础信息
        SysUser user = this.getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getId, userId)
                .select(
                        SysUser::getId,
                        SysUser::getUsername,
                        SysUser::getNickname,
                        SysUser::getAvatar
                )
        );

        // entity -> VO
        UserInfoVO userInfoVO = userConverter.toUserInfoVo(user);

        // 用户角色集合
        Set<String> roles = SecurityUtil.getRoles();
        userInfoVO.setRoles(roles);


        // 用户权限集合
        Set<String> perms = redisUtil.getCacheObject(RedisKeyConstants.USER_PERMS_CACHE_PREFIX + userInfoVO.getUserId());
        userInfoVO.setPerms(perms);

        return userInfoVO;
    }

    /**
     * 新增用户
     *
     * @param userForm 用户表单
     * @return 是否增加成功
     */
    @Override
    public boolean saveUser(UserForm userForm) {

        return true;
    }
    /**
     * 获取用户详情
     *
     * @param userId 用户id
     * @return 用户表单数据
     */
    @Override
    public UserForm getUserFormData(Long userId) {
        // TODO UserFromBO, UserFrom , UserBO ... 中应该修改性别属性为枚举
        UserFromBO userFormData = baseMapper.getUserDetail(userId);
        return userConverter.bo2Form(userFormData);
    }
}

